package es.mfp.practicos.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManagerFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Transactional;

public class GenericDaoImpl<T, PK extends Serializable> extends JpaDaoSupport implements
		GenericDao<T, PK> {

	private static Log logger = LogFactory.getFactory().getInstance(GenericDaoImpl.class);

	@SuppressWarnings("rawtypes")
	private Class persistentClass;

	/**
	 * Set the JPA EntityManagerFactory.
	 * 
	 * @param fooEntityManagerFactory
	 */
	@Autowired
	@Required
	public void setJpaEntityManagerFactory(EntityManagerFactory entityManagerFactory) {
		super.setEntityManagerFactory(entityManagerFactory);
	}

	@SuppressWarnings("rawtypes")
	public GenericDaoImpl() {
		this.persistentClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass())
				.getActualTypeArguments()[0];
	}

	@Override
	@Transactional(readOnly = false)
	public void insert(T t) {
		getJpaTemplate().persist(t);
	}

	@SuppressWarnings("unchecked")
	@Override
	@Transactional(readOnly = true)
	public T findByPK(PK id) {
		return (T) getJpaTemplate().find(persistentClass, id);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> getAll() {
		List<T> entities = null;

		try {
			String s = "select c from " + persistentClass.getSimpleName() + " c";
			entities = getJpaTemplate().find(s);
		} catch (Exception e) {

			logger.error(e.getStackTrace());
		}
		return entities;
	}

	@Override
	@Transactional(readOnly = false)
	public void remove(T t) {
		getJpaTemplate().remove(getJpaTemplate().merge(t));
	}

	@Override
	@Transactional(readOnly = false)
	public void update(T object) {
		getJpaTemplate().merge(object);
	}

}
